﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using Microsoft.Practices.Unity;
using Vit.Common;
using Vit.Common.Helpers;
using Vit.Common.Extensions;
using Vit.Common.Providers;
using Vit.Common.Providers.Localization;
using Vit.Web;
using Vit.Web.Models;
using Vit.Web.Providers;
using Vit.Web.Mvc.Results;

namespace Vit.AdminModule.Areas.Admin.Controllers
{
    [Authorize]
    public class JsonLocalController : Vit.Web.Mvc.Controllers.ControllerBase
    {
        JsonResourceProvider provider = Unity.Current.ResolveAny<ILocalizationProvider>().OfType<JsonResourceProvider>().First();

        public ActionResult Index()
        {
            ViewBag.Languages = provider.Resources.Select(o => string.IsNullOrWhiteSpace(o.CultureInfoName) ? "Default" : o.CultureInfoName).Distinct();
            var res = provider.Resources;
            return View(res);
        }

        [HttpGet]
        public ActionResult Create()
        {
            LocalizationItem item = new LocalizationItem();
            return View("DataCreate", item);
        }

        [HttpPost]
        public ActionResult Create(LocalizationItem item)
        {
            if (item.CultureInfo.ToLower() == "default")
                item.CultureInfo = "";
            provider.SetString(item.AssemblyName, item.Name, item.CultureInfo, item.Value);
            provider.Save();
            ViewBag.Message = Locale.GetString("Vit.Web", "DataController_SaveSuccessfully");
            return Refresh();
        }

        [HttpPost]
        public ActionResult Delete(FormCollection form)
        {
            foreach (string fid in form.AllKeys.Where(o => o.StartsWith("cb_")))
            {
                string[] keys = form[fid].Split(new char[] { '$' }, StringSplitOptions.RemoveEmptyEntries);
                if (keys[1].ToLower() == "default")
                    keys[1] = "";
                provider.SetString(keys[0], keys[2], keys[1], null);
            }
            provider.Save();
            ViewBag.Message = Locale.GetString("Vit.Web", "DataController_DeleteSuccessfully");
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult Save(FormCollection form)
        {
            foreach (string fid in form.AllKeys.Where(o => !o.StartsWith("cb_")))
            {
                string[] keys = fid.Split(new char[] { '$' }, StringSplitOptions.RemoveEmptyEntries);
                if (keys[1].ToLower() == "default")
                    keys[1] = "";
                provider.SetString(keys[0], keys[2], keys[1], form[fid]);
            }
            provider.Save();
            ViewBag.Message = Locale.GetString("Vit.Web", "DataController_SaveSuccessfully");
            return RedirectToAction("Index");
        }

        [HttpGet]
        public ActionResult AppendAsm(string id)
        {
            ViewData.Model = id;
            return View();
        }

        [HttpPost]
        public ActionResult AppendAsm(FormCollection form)
        {
            var lang = form["Language"];
            if (lang.ToLower() == "default")
                lang = "";
            var asmName = form["AssemblyName"];
            var nsName = form["NameSpace"];
            bool rewrite = false;
            if (form["Rewrite"] == "on")
                rewrite = true;
            string file = Server.MapPath(string.Format("/bin/{0}.dll", asmName));
            Assembly asm = Assembly.LoadFrom(file);
            var langRes = provider.Resources.Where(o => o.CultureInfoName == lang);
            foreach (var type in asm.GetTypes().Where(o => o.Namespace != null && o.Namespace.ToLower() == nsName.ToLower()))
            {
                if (type.IsClass == false || type.IsAbstract || type.IsVisible == false || type.IsNested)
                    continue;

                // add type name resource
                string resName = type.Name;
                AddResource(nsName, resName, lang, resName, rewrite);

                // add properies' resources
                var props = type.GetProperties().Where(o => !o.PropertyType.IsInterface && !o.PropertyType.IsAbstract && !o.PropertyType.IsArray && o.PropertyType.IsVisible);
                foreach (var prop in props)
                {
                    resName = string.Format("{0}_{1}", type.Name, prop.Name);
                    AddResource(nsName, resName, lang, prop.Name, rewrite);
                }
            }

            provider.Save();
            ViewBag.Message = Locale.GetString("Vit.Web", "DataController_SaveSuccessfully");

            return Refresh();
        }

        [HttpGet]
        public ActionResult AppendView(string id)
        {
            if (id.ToLower() == "default")
                id = "";

            var root = new DirectoryInfo(Request.PhysicalApplicationPath);
            var dirs = root.GetDirectories("Views", SearchOption.AllDirectories)
                .Concat(root.GetDirectories("Containers", SearchOption.AllDirectories))
                .Concat(root.GetDirectories("Controls", SearchOption.AllDirectories))
                .Concat(root.GetDirectories("Eidtors", SearchOption.AllDirectories))
                .Concat(root.GetDirectories("Layouts", SearchOption.AllDirectories))
                .Concat(root.GetDirectories("Pages", SearchOption.AllDirectories));
            List<FileInfo> files = new List<FileInfo>();
            foreach (var d in dirs)
                files.AddRange(d.GetFiles("*.cshtml", SearchOption.AllDirectories));

            string pattern = @"Locale.GetString\(\""([^\""]+)"", \""([^\""]+)\""\)";
            Regex regex = new Regex(pattern);
            foreach (var file in files)
            {
                StreamReader sr = new StreamReader(file.FullName);
                string content = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();

                MatchCollection matches = regex.Matches(content);
                foreach (Match match in matches)
                {
                    string nsName = match.Groups[1].Value;
                    string resName = match.Groups[2].Value;
                    AddResource(nsName, resName, id, resName, false);
                }
            }

            provider.Save();
            ViewBag.Message = Locale.GetString("Vit.Web", "DataController_SaveSuccessfully");

            return RedirectToAction("Index");
        }

        [HttpGet]
        public ActionResult Copy(string id)
        {
            ViewData.Model = id;
            return View();
        }

        [HttpPost]
        public ActionResult Copy(FormCollection form)
        {
            var lang = form["Language"];
            var fromLang = form["FromLanguage"];
            if (lang.ToLower() == "default")
                lang = "";
            if (fromLang.ToLower() == "default")
                fromLang = "";
            var nsName = form["NameSpace"];
            bool rewrite = false;
            if (form["Rewrite"] == "on")
                rewrite = true;
            var reslist = string.IsNullOrWhiteSpace(nsName) ? provider.Resources.Where(o => o.CultureInfoName == fromLang) : provider.Resources.Where(o => o.AssemblyName == nsName.Replace(".", "_") && o.CultureInfoName == fromLang);
            foreach (var res in reslist)
            {
                foreach (var prop in res.Resources)
                {
                    AddResource(nsName, prop.Name, lang, prop.Value, rewrite);
                }
            }

            provider.Save();
            ViewBag.Message = Locale.GetString("Vit.Web", "DataController_SaveSuccessfully");

            return Refresh();
        }

        private void AddResource(string nsName, string resName, string lang, string val, bool rewrite)
        {
            if (rewrite)
            {
                provider.SetString(nsName, resName, lang, val);
            }
            else
            {
                var langRes = provider.Resources.Where(o => o.CultureInfoName == lang && o.AssemblyName == nsName);
                bool exists = langRes.Any(o => o.Resources.Any(r => r.Name == resName));
                if (!exists)
                {
                    provider.SetString(nsName, resName, lang, val);
                }
            }
        }
    }
}
